package org.deloitte.activiti.listeners;

import java.util.List;
import java.util.logging.Logger;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.IdentityLinkEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.task.IdentityLinkType;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;

public class NotificationListener implements TaskListener {
	   private static Logger log = Logger.getLogger(NotificationListener.class.getName());

	   @Override
	   public void notify(DelegateTask delegateTask) {
	      TaskEntity task = (TaskEntity)delegateTask;
	      String assignee = task.getAssignee();
	      List<IdentityLinkEntity> identityLinks = task.getIdentityLinks();
	      
	      StringBuffer message = new StringBuffer("");
	      
	      message.append("You have a new assigned task. <br/><br/>");
	      message.append("<a href=\"http://activitiwfdb.appspot.com/dashboard\">");
	      message.append(task.getName());
	      message.append("</a> <br/><br/>");
	      message.append("Please complete this task asap.");
	      
	      
	      if(assignee != null && assignee.length() > 0) {
	         User user = Context.getProcessEngineConfiguration().getIdentityService().createUserQuery().userId(assignee).singleResult();
	         sendNotification(user, message.toString());
	      }
	      
	      for(IdentityLinkEntity link : identityLinks) {
	         if(link.getType().equals(IdentityLinkType.CANDIDATE)) {
	            if(link.isUser()) {
	               User user = Context.getProcessEngineConfiguration().getIdentityService().createUserQuery().userId(link.getUserId()).singleResult();
	               sendNotification(user, message.toString());
	            }
	            if(link.isGroup()) {
	               List<User> users = Context.getProcessEngineConfiguration().getIdentityService().createUserQuery().memberOfGroup(link.getGroupId()).list();
	               for(User user : users) {
	                  sendNotification(user, message.toString());
	               }
	            }
	         } 
	         else if(link.getType().equals(IdentityLinkType.ASSIGNEE)) {
	            if(link.isUser()) {
		               User user = Context.getProcessEngineConfiguration().getIdentityService().createUserQuery().userId(link.getUserId()).singleResult();
		               sendNotification(user, message.toString());
		            }
		            if(link.isGroup()) {
		               List<User> users = Context.getProcessEngineConfiguration().getIdentityService().createUserQuery().memberOfGroup(link.getGroupId()).list();
		               for(User user : users) {
		                  sendNotification(user, message.toString());
		               }
		            }	        	 
	         }
	      }
	      
	   }
	   
	   protected void sendNotification(User user, String message) {

	      HtmlEmail email = new HtmlEmail();
	      try {
	         email.setHtmlMsg(message);
	         email.addTo(user.getEmail()); 
	         email.setSubject("Activiti Assignment Notification");
	         email.setFrom("payrollmgtsystem@gmail.com");

	         setMailServerProperties(email);

	         email.send();
	      } catch (EmailException e) {
	         throw new ActivitiException("Could not send e-mail:" + e.getMessage(), e);
	      }
	   }
	   
	   protected void setMailServerProperties(Email email) {
	      ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration();

	      String host = processEngineConfiguration.getMailServerHost();
	      if (host == null) {
	         throw new ActivitiException("Could not send email: no SMTP host is configured");
	      }
	      email.setHostName(host);
    	  email.setTLS(true);

	      int port = processEngineConfiguration.getMailServerPort();
	      email.setSmtpPort(port);

	      String user = processEngineConfiguration.getMailServerUsername();
	      String password = processEngineConfiguration.getMailServerPassword();
	      if (user != null && password != null) {
	         email.setAuthentication(user, password);
	      }
	   }

}
